using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Test_Drag_N_drop
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        private bool titleScreen = true;
        private Texture2D titleScreenTexture;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        private BlockPoolZone zone3;
        private ConstructZone zone2;
        private ResultZone zone1;
        private MouseState mouseState;
        private MouseState previousMouseState;
        private KeyboardState keyboardState;
        private int screenWidth;
        private int screenHeight;
        private ButtonRun runButton;
        private ButtonReset resetButton;
        private MessageBox msgBox;
        private ButtonHelp helpButton;
        private LaunchButton launchButton;
        private HELP helpWindow;
        private bool runningProg = false;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.ToggleFullScreen();
            screenHeight = graphics.GraphicsDevice.Viewport.Height;
            screenWidth = graphics.GraphicsDevice.Viewport.Width;
            //screenHeight = 500;
            //screenWidth = 900;
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            this.IsMouseVisible = true;
            runButton = new ButtonRun(this);
            resetButton = new ButtonReset(this);
            helpButton = new ButtonHelp(this);
            launchButton = new LaunchButton(this);
            zone3 = new BlockPoolZone();
            zone2 = ConstructZone.getInstance();
            zone1 = ResultZone.getInstance();
            msgBox = new MessageBox(this);
            helpWindow = new HELP();
            runButton.Initialize(screenWidth / 2 +100, screenHeight - 80);
            resetButton.Initialize((screenWidth / 2) - 100, screenHeight - 80);
            helpButton.Initialize(screenWidth / 6, 80);
            launchButton.Initialize(screenWidth /2, 3 * screenHeight / 4);
            zone3.Initialize(GraphicsDevice, screenWidth, screenHeight);
            zone2.Initialize(Content, GraphicsDevice, screenWidth, screenHeight);
            zone1.Initialize(screenWidth, screenHeight);
            msgBox.Initialize(screenWidth / 6, screenHeight - 100);
            helpWindow.Initialize(screenWidth/2, screenHeight/2);
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            launchButton.LoadContent(Content);
            runButton.LoadContent(Content);
            resetButton.LoadContent(Content);
            helpButton.LoadContent(Content);
            helpWindow.LoadContent(Content);
            zone1.LoadContent(Content);
            zone3.LoadContent(Content);
            zone2.LoadContent();
            msgBox.LoadContent(Content);
            titleScreenTexture = Content.Load<Texture2D>("TitleScreen");
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {   

            keyboardState = Keyboard.GetState();
            previousMouseState = mouseState;
            mouseState = Mouse.GetState();
            if (titleScreen)
            {
                launchButton.Update(gameTime, mouseState, previousMouseState);
            }
            else
            {
                if (runningProg)
                {
                    int result = zone1.run();
                    if (result != 0)
                    {
                        msgBox.setMessage(result);
                        msgBox.setActive(true);
                        runningProg = false;
                    }
                }
                else
                {
                    zone2.Update(gameTime, mouseState, previousMouseState);
                    zone3.Update(gameTime, mouseState, previousMouseState);
                    runButton.Update(gameTime, mouseState, previousMouseState);
                    resetButton.Update(gameTime, mouseState, previousMouseState);
                    helpButton.Update(gameTime, mouseState, previousMouseState);
                }
            }
            // Allows the game to exit
            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }

            // TODO: Add your update logic here
            helpWindow.Update(gameTime, mouseState, previousMouseState);
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.FromNonPremultiplied(249, 209, 174, 255));

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            zone2.Draw(spriteBatch, gameTime);
            zone3.Draw(spriteBatch, gameTime);
            zone2.DrawNewBlock(spriteBatch, gameTime);
            zone1.Draw(spriteBatch, gameTime);
            runButton.Draw(spriteBatch, gameTime);
            resetButton.Draw(spriteBatch, gameTime);
            helpButton.Draw(spriteBatch, gameTime);
            msgBox.Draw(spriteBatch, gameTime);
            if (titleScreen)
            {
                spriteBatch.Draw(titleScreenTexture, new Rectangle(0,0, screenWidth, screenHeight), new Rectangle(0,0,1366, 768), Color.White);
                launchButton.Draw(spriteBatch, gameTime);
            }
            helpWindow.Draw(spriteBatch, gameTime);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        public void RunProg()
        {
            runningProg = true;
            msgBox.setActive(false);
        }
        
        public void ClearConstructZone()
        {
            zone2.clearList();
        }
        
        public void launchL2C()
        {
            titleScreen = false;
        }
    
        public void launchHelp()
        {
            helpWindow.setActive();
        }
    }
}
